"""会员相关 API Router"""
from datetime import datetime
import secrets
from typing_extensions import Annotated
, Body, Depends, File, Form, Path, Query,
    Request, status, UploadFile
)
from sqlalchemy import delete

from bbs.social import SocialAuthService
from core.database import db_session
from core.models import Member
from lib.pbkdf2 import validate_password
from lib.mail import send_password_reset_mail, send_register_admin_mail, send_register_mail

from api.v1.dependencies.member import (
    get_current_member, validate_certify_email_member, validate_create_data, validate_update_data
)
from api.v1.models import MemberRefreshToken
from api.v1.models.member import (
    CreateMember, MemberMeResponse, SearchMemberId, SearchMemberPassword,
    ResetMemberPassword, MemberResponse, RegisterResponse,
    SearchMemberIdResponse, UpdateMember
)
from api.v1.models.response import (
    MessageResponse, response_401, response_403, response_404, response_409, response_422
)
from api.v1.service.member import (
    MemberServiceAPI,
    MemberImageServiceAPI as ImageService,
    ValidateMemberAPI
)
from api.v1.service.point import PointServiceAPI

router = APIRouter()


@router.post("/members",
             summary="成员资格",
             status_code=status.HTTP_201_CREATED,
             responses={**response_403, **response_409, **response_422})
async def create_member(
    request: Request,
    background_tasks: BackgroundTasks,
    service: Annotated[MemberServiceAPI, Depends()],
    point_service: Annotated[PointServiceAPI, Depends()],
    data: Annotated[CreateMember, Depends(validate_create_data)]
) -> RegisterResponse:
# 处理会员注册。

# ####与会员注册一起处理的任务
# -会员加入&推荐人积分发放
# -发送会员注册邮件（设置邮件发送时）
# -向管理员发送会员注册邮件（设置邮件发送时

    config = request.state.config
    member = service.create_member(data)

    # 支付会员加入积分
    register_point = getattr(config, "cf_register_point", 0)
    point_service.save_point(member.mb_id, register_point, "祝贺会员",
                             "@member", member.mb_id, "成员资格")

    #支付推荐积分
    mb_recommend = data.mb_recommend
    if getattr(config, "cf_use_recommend", False) and mb_recommend:
        recommend_point = getattr(config, "cf_recommend_point", 0)
        point_service.save_point(mb_recommend, recommend_point, f"{member.mb_id}的建议",
                                 "@member", mb_recommend, f"{member.mb_id} 待定")

    # 处理会员订阅邮件发送（后台）
    background_tasks.add_task(send_register_mail, request, member)
    background_tasks.add_task(send_register_admin_mail, request, member)

    message = "会员资格已完成."
    if member.mb_email_certify2:
        message += " 请继续进行电子邮件身份验证."

    return {
        "message": message,
        "mb_id": member.mb_id,
        "mb_name": member.mb_name,
        "mb_nick": member.mb_nick,
    }


@router.put("/members/{mb_id}/email-certification/change",
            summary="更改身份验证电子邮件",
            responses={**response_403, **response_409, **response_422})
async def certificate_email_change(
    request: Request,
    db: db_session,
    member_vaildate: Annotated[ValidateMemberAPI, Depends()],
    member: Annotated[Member, Depends(validate_certify_email_member)],
    email: Annotated[str, Body(..., title="电子邮件", description="要更改的电子邮件")],
) -> MessageResponse:
# """
# 更改未处理邮件验证的成员的邮件，并重新发送验证邮件。
#就是成员更改了邮件，需要更改数据库记录，并重新发送验证邮件；   
# #### Request Body
# -email:要更改的电子邮件地址
# -password:会员密码
# """
    member_vaildate.valid_email(email, member.mb_id)

    # 更改您的电子邮件和验证码
    member.mb_email = email
    member.mb_email_certify2 = secrets.token_hex(16)
    db.commit()
    db.refresh(member)

    # 重新发送身份验证邮件
    await send_register_mail(request, member)

    return {"message": f"{email} 我将认证邮件重新发送到地址."}


@router.put("/members/{mb_id}/email-certification",
            summary="成员资格的邮件身份验证处理")
async def certificate_email(
    db: db_session,
    member_service: Annotated[MemberServiceAPI, Depends()],
    mb_id: Annotated[str, Path(title="会员Id", description="会员Id")],
    certify_key: str = Query(..., title="身份验证密钥", description="电子邮件身份验证密钥")
) -> MessageResponse:
    """
注册会员时，处理邮件认证。
如果在“管理员>首选参数”中禁用邮件身份验证，则不使用此API。
    """
    member = member_service.read_email_non_certify_member(mb_id, certify_key)
    member.mb_email_certify = datetime.now()
    member.mb_email_certify2 = ""
    db.commit()

    return {"message": "电子邮件验证已完成。"}


@router.get("/members/me",
            summary="当前登录会员信息查询",
            responses={**response_401, **response_403, **response_404})
async def read_member_me(
    member: Annotated[Member, Depends(get_current_member)]
) -> MemberMeResponse:
    """
查看通过JWT令牌认证的会员信息。
-无法查询退出或被阻止的会员。
-无法查看未完成电子邮件身份验证的会员。
    """
    return member


@router.post("/members/password_certification",
            summary="检查您的密码",
            responses={**response_401, **response_403, **response_422}
            )
async def password_certification(
    service: Annotated[MemberServiceAPI, Depends()],
    member: Annotated[Member, Depends(get_current_member)],
    password: Annotated[str, Body(..., title="密码", description="密码")],
) -> MessageResponse:
# 验证通过JWT令牌解码获得的成员与输入的密码是否一致。
    if not validate_password(password, member.mb_password):
        service.raise_exception(status_code=403, detail="密码不匹配.")

    return {"message": "密码已确认."}


@router.get("/members/{mb_id}",
            summary="会员信息查询",
            responses={**response_401, **response_403, **response_404})
async def read_member(
    service: Annotated[MemberServiceAPI, Depends()],
    current_member: Annotated[Member, Depends(get_current_member)],
    mb_id: Annotated[str, Path(title="会员Id", description="会员Id")],
) -> MemberResponse:
    """
查询会员信息。
-如果您已公开自己&对方的信息，则可以查询。
    """
    return service.get_member_profile(mb_id, current_member)


@router.put("/member",
            summary="编辑会员信息",
            responses={**response_401, **response_403,
                       **response_409, **response_422})
async def update_member(
    service: Annotated[MemberServiceAPI, Depends()],
    member: Annotated[Member, Depends(get_current_member)],
    data: Annotated[UpdateMember, Depends(validate_update_data)],
) -> MessageResponse:
#   “修改通过JWT令牌认证的会员信息。”
    service.update_member(member, data.model_dump())

    return {"message": "会员信息已修复."}


@router.put("/member/image",
            summary="成员图标&图像校正",
            responses={**response_401, **response_403, **response_422})
async def update_member_image(
    service: Annotated[ImageService, Depends()],
    member: Annotated[Member, Depends(get_current_member)],
    mb_img: Annotated[UploadFile, File(title="附件1")] = None,
    mb_icon: Annotated[UploadFile, File(title="附件2")] = None,
    del_mb_img: Annotated[int, Form(title="附件1 是否删除")] = 0,
    del_mb_icon: Annotated[int, Form(title="附件2 是否删除")] = 0,
) -> MessageResponse:
    """修改通过JWT令牌认证会员的图标和图像。"""
    service.update_image_file(member.mb_id, 'image', mb_img, del_mb_img)
    service.update_image_file(member.mb_id, 'icon', mb_icon, del_mb_icon)

    return {"message": "成员图像已修复."}


@router.delete("/member",
              summary="会员退出",
              responses={**response_401, **response_403})
async def leave_member(
    db: db_session,
    service: Annotated[MemberServiceAPI, Depends()],
    member: Annotated[Member, Depends(get_current_member)]
) -> MessageResponse:
    """
通过JWT令牌注销经过认证的会员。
-数据实际上不会被删除，只进行注销处理。
    """
    service.leave_member(member)

    # 解除社交登录关联
    SocialAuthService.unlink_social_login(member.mb_id)

    # 删除令牌
    db.execute(delete(MemberRefreshToken)
               .where(MemberRefreshToken.mb_id == member.mb_id))
    db.commit()

    return {"message": "已办理会员退保."}


@router.post("/members/search/id",
             summary="查找会员的Idias",
             responses={**response_404, **response_422})
async def find_member_id(
    service: Annotated[MemberServiceAPI, Depends()],
    data: SearchMemberId
) -> SearchMemberIdResponse:
    """
姓名，通过电子邮件查找会员ID。
-ID返回中间字母*。
-通过社交登录注册的会员无法找到ID。
    """
    mb_id, register_date = service.find_id(data.mb_name, data.mb_email)

    return {
        "mb_id": mb_id,
        "register_date": register_date
    }


@router.post("/members/search/password",
             summary="发送密码重置邮件",
             responses={**response_404, **response_422})
async def find_member_password_api(
    request: Request,
    background_tasks: BackgroundTasks,
    member_service: Annotated[MemberServiceAPI, Depends()],
    data: SearchMemberPassword
) -> MessageResponse:
# “身份，通过电子邮件向您发送可以重置密码的链接。”
    member = member_service.find_member_from_password_info(data.mb_id, data.mb_email)
    # 密码重置邮件发送处理（后台）
    background_tasks.add_task(send_password_reset_mail, request, member)

    return {"message": "已发送密码重置邮件."}


@router.patch("/members/{mb_id}/password/{token}",
              name="reset_password_api",
              summary="重置密码",
              responses={**response_404, **response_422})
async def reset_password(
    member_service: Annotated[MemberServiceAPI, Depends()],
    mb_id: Annotated[str, Path(title="会员Id", description="会员Id")],
    token: Annotated[str, Path(title="令牌", description="密码重置令牌")],
    data: ResetMemberPassword
) -> MessageResponse:
    """我们重置了密码."""
    member_service.reset_password(mb_id, token, data.password)

    return {"message": "密码已重置."}
